package com.unlcn.ils.wms.backend.service.inbound.impl;

import cn.huiyunche.commons.exception.BusinessException;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.unlcn.ils.wms.backend.bo.inboundBO.WmsInboundCheckBO;
import com.unlcn.ils.wms.backend.bo.inboundBO.WmsInventoryLocationBO;
import com.unlcn.ils.wms.backend.bo.stockBO.WmsInventoryBO;
import com.unlcn.ils.wms.backend.dto.bigscreenDTO.InvoicingStatisticsChartDataDTO;
import com.unlcn.ils.wms.backend.dto.bigscreenDTO.InvoicingStatisticsLineBody;
import com.unlcn.ils.wms.backend.dto.bigscreenDTO.InvoicingStatisticsLineDataDTO;
import com.unlcn.ils.wms.backend.enums.DeleteFlagEnum;
import com.unlcn.ils.wms.backend.enums.InventoryLocationStatusEnum;
import com.unlcn.ils.wms.backend.enums.WarehouseEnum;
import com.unlcn.ils.wms.backend.enums.WhCodeEnum;
import com.unlcn.ils.wms.backend.service.inbound.WmsInventoryService;
import com.unlcn.ils.wms.backend.util.DateUtils;
import com.unlcn.ils.wms.backend.util.ObjectToMapUtils;
import com.unlcn.ils.wms.backend.util.TimeUtil;
import com.unlcn.ils.wms.base.businessDTO.inbound.AsnOrderDTO;
import com.unlcn.ils.wms.base.businessDTO.stock.WmsInventoryDTO;
import com.unlcn.ils.wms.base.businessDTO.stock.WmsInventoryLocationDTO;
import com.unlcn.ils.wms.base.businessDTO.stock.WmsInventoryQueryDTO;
import com.unlcn.ils.wms.base.dto.*;
import com.unlcn.ils.wms.base.mapper.additional.WmsInboundAsnOrderAddMapper;
import com.unlcn.ils.wms.base.mapper.additional.WmsInventoryExtMapper;
import com.unlcn.ils.wms.base.mapper.additional.WmsInventoryLocationExtMapper;
import com.unlcn.ils.wms.base.mapper.additional.wmsOutbound.WmsOutboundTaskExtMapper;
import com.unlcn.ils.wms.base.mapper.bigscreen.BiInOutInventoryChartMapper;
import com.unlcn.ils.wms.base.mapper.extmapper.BiDistributionHeadExtMapper;
import com.unlcn.ils.wms.base.mapper.outbound.WmsOutboundTaskMapper;
import com.unlcn.ils.wms.base.mapper.stock.WmsInventoryLocationMapper;
import com.unlcn.ils.wms.base.mapper.stock.WmsInventoryMapper;
import com.unlcn.ils.wms.base.model.bigscreen.BiDistributionHead;
import com.unlcn.ils.wms.base.model.bigscreen.BiInOutInventoryChart;
import com.unlcn.ils.wms.base.model.bigscreen.BiInOutInventoryChartExample;
import com.unlcn.ils.wms.base.model.outbound.WmsOutboundTask;
import com.unlcn.ils.wms.base.model.outbound.WmsOutboundTaskExample;
import com.unlcn.ils.wms.base.model.stock.WmsInventory;
import com.unlcn.ils.wms.base.model.stock.WmsInventoryExample;
import com.unlcn.ils.wms.base.model.stock.WmsInventoryLocation;
import com.unlcn.ils.wms.base.model.stock.WmsInventoryLocationExample;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 库存service
 * Created by DELL on 2017/8/8.
 */
@Service
public class WmsInventoryServiceImpl implements WmsInventoryService {

    private Logger logger = LoggerFactory.getLogger(WmsInventoryServiceImpl.class);

    @Autowired
    private WmsInventoryMapper wmsInventoryMapper;

    @Autowired
    private WmsInventoryLocationMapper wmsInventoryLocationMapper;

    @Autowired
    private WmsInventoryExtMapper wmsInventoryExtMapper;

    @Autowired
    private WmsInboundAsnOrderAddMapper wmsInboundAsnOrderAddMapper;

    @Autowired
    private WmsInventoryLocationExtMapper wmsInventoryLocationExtMapper;

    @Autowired
    private WmsOutboundTaskExtMapper wmsOutboundTaskExtMapper;

    @Autowired
    private BiInOutInventoryChartMapper biInOutInventoryChartMapper;

    @Autowired
    private WmsOutboundTaskMapper wmsOutboundTaskMapper;

    /**
     * 库存的分页查询 - 西南
     *
     * @param wmsInventoryQueryDTO 参数封装
     * @return 返回值
     * @throws IllegalAccessException 异常
     */
    @Override
    public Map<String, Object> queryListByInventory(WmsInventoryQueryDTO wmsInventoryQueryDTO) throws IllegalAccessException {
        if (Objects.equals(wmsInventoryQueryDTO, null)) {
            logger.info("WmsInventoryServiceImpl.queryListByInventory queryDTO not be null");
            throw new IllegalArgumentException("分页参数不能为空");
        }
        Map<String, Object> resultMap = Maps.newHashMap();

        wmsInventoryQueryDTO.setLimitStart(wmsInventoryQueryDTO.getStartIndex());
        wmsInventoryQueryDTO.setLimitEnd(wmsInventoryQueryDTO.getPageSize());

        Map<String, Object> paramMap = ObjectToMapUtils.objectToMap(wmsInventoryQueryDTO);
        List<WmsInventoryDTO> infos = wmsInventoryExtMapper.queryForList(paramMap);
        List<WmsInventoryBO> bos = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(infos)) {
            infos.forEach(v -> {
                WmsInventoryBO bo = new WmsInventoryBO();
                BeanUtils.copyProperties(v, bo);
                BeanUtils.copyProperties(v.getWmsInventoryLocationDTOList().get(0), bo);
                bos.add(bo);
            });
            resultMap.put("wmsInventoryList", bos);
        }
        wmsInventoryQueryDTO.setPageNo(wmsInventoryQueryDTO.getStartIndex());
        wmsInventoryQueryDTO.setPageSize(wmsInventoryQueryDTO.getPageSize());
        wmsInventoryQueryDTO.setTotalRecord(wmsInventoryExtMapper.queryForCount(paramMap));
        resultMap.put("wmsInventoryBO", wmsInventoryQueryDTO);
        return resultMap;
    }


    /**
     * 库存查询 - 君马
     * <p>
     * 2018-1-23
     * 库存查询页面增加“物料代码”、“物料名称”、“颜色代码”、“颜色”字段显示，导出的文件中也需要包含这四个字段
     * 查询条件中增加“物料名称”、“颜色”、“库存状态”
     * 2018-4-23 因入库通知单重构,君马库存查询列表调整
     * 2018-5-16 增加库存查询页面库龄筛选功能
     * </p>
     *
     * @param queryDTO 参数封装
     * @return 返回值
     * @throws Exception 异常
     */
    @Override
    public Map<String, Object> queryInventoryListForJunMa(WmsInventoryQueryDTO queryDTO) throws Exception {
        logger.info("WmsInventoryServiceImpl.queryInventoryListForJunMa param: {}", JSONObject.toJSONString(queryDTO));
        if (Objects.equals(queryDTO, null)) {
            throw new BusinessException("分页参数不能为空");
        }
        Map<String, Object> resultMap = Maps.newHashMap();
        queryDTO.setLimitStart(queryDTO.getStartIndex());
        queryDTO.setLimitEnd(queryDTO.getPageSize());
        Map<String, Object> paramMap = ObjectToMapUtils.objectToMap(queryDTO);
        if (StringUtils.isNotBlank(queryDTO.getInventoryAge())) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(new Date());
            cal.add(Calendar.DATE, -(new Integer(queryDTO.getInventoryAge()) - 1));
            int year = cal.get(Calendar.YEAR);
            int month = cal.get(Calendar.MONTH);
            int day = cal.get(Calendar.DATE);
            cal.set(year, month, day, 0, 0, 0);
            Date startTime = cal.getTime();
            paramMap.put("inventoryStartTime", startTime);
            cal.set(year, month, day, 23, 59, 59);
            Date endTime = cal.getTime();
            paramMap.put("inventoryEndTime", endTime);
        }


        //List<WmsInventoryLocationExtDTO> locationExtDTOList = wmsInventoryExtMapper.queryInventoryLocationForJunMa(paramMap);
        List<WmsInventoryLocationExtDTO> locationExtDTOList = wmsInventoryExtMapper.queryInventoryLocationForJunMaWithNotice(paramMap);
        //计算库龄/getInventoryManageList
        DateTimeFormatter format = DateTimeFormat.forPattern(DateUtils.YYYY_MM_DD);
        DateTime nowDate = new DateTime();
        if (CollectionUtils.isNotEmpty(locationExtDTOList)) {
            locationExtDTOList.stream()
                    .filter(dto -> dto != null && dto.getGmtCreate() != null)
                    .forEach(dto -> {
                        DateTime gmtCreate = new DateTime(dto.getGmtCreate());//入库时间
                        DateTime startTime = DateTime.parse(gmtCreate.toString(DateUtils.YYYY_MM_DD), format);
                        DateTime endTime = DateTime.parse(nowDate.toString(DateUtils.YYYY_MM_DD), format);
                        int days = Days.daysBetween(startTime, endTime).getDays();
                        if (days >= 0) {
                            dto.setWarehouseAge(days + 1);
                        }
                    });
        }
        resultMap.put("wmsInventoryList", locationExtDTOList);
        queryDTO.setPageNo(queryDTO.getStartIndex());
        queryDTO.setPageSize(queryDTO.getPageSize());
        //queryDTO.setTotalRecord(wmsInventoryExtMapper.countForJunMaList(paramMap));
        queryDTO.setTotalRecord(wmsInventoryExtMapper.countForJunMaListWithNotice(paramMap));
        resultMap.put("wmsInventoryBO", queryDTO);
        return resultMap;
    }

    /**
     * 更新冻结库存/锁定库存信息
     * <p>
     * 2018-3-2  新需求说明,增加君马库根据id冻结相应车辆库存状态
     * </p>
     *
     * @param freezeDTO 参数封装
     */
    @Override
    public void updateStockFreeze(WmsInventoryFreezeDTO freezeDTO) {
        logger.info("WmsInventoryServiceImpl.updateStockFreeze params:", JSONObject.toJSONString(freezeDTO));
        if (freezeDTO == null)
            throw new BusinessException("参数不能为空!");
        String whCode = freezeDTO.getWhCode();
        if (StringUtils.isBlank(whCode))
            throw new BusinessException("仓库code不能为空!");
        if (!(WhCodeEnum.JM_CS.getValue().equals(whCode) || WhCodeEnum.JM_XY.getValue().equals(whCode)))
            throw new BusinessException("该仓库不支持此操作!");
        String invlocIds = freezeDTO.getInvlocIds();
        if (StringUtils.isBlank(invlocIds))
            throw new BusinessException("请选择要冻结的车辆");
        String[] sp_ids = invlocIds.split(",");
        List<String> ids = Arrays.asList(sp_ids);
        List<WmsInventoryLocation> list = wmsInventoryLocationExtMapper.selectNormalListByIds(ids);
        StringBuilder cant_vin = new StringBuilder();
        list.forEach(v -> {
            if (!InventoryLocationStatusEnum.NORMAL_10.getCode().equals(v.getStatus())) {
                cant_vin.append(v.getInvlocVin()).append(",");
            }
        });
        if (StringUtils.isNotBlank(cant_vin)) {
            throw new BusinessException(cant_vin.substring(0, cant_vin.length() - 1) + "非正常在库状态不能进行锁定!");
        }
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("freeze_status", InventoryLocationStatusEnum.INVENTORY_FREEZE.getCode());
        params.put("ids", ids);
        params.put("whCode", freezeDTO.getWhCode());
        wmsInventoryLocationExtMapper.updateFreezeStatusByIds(params);
    }

    /**
     * 更新库存信息为正常状态
     * <p>
     * 2018-3-2  新需求说明,增加君马库根据id解锁相应车辆库存状态
     * </p>
     *
     * @param freezeDTO 参数封装
     */
    @Override
    public void updateStockNormal(WmsInventoryFreezeDTO freezeDTO) {
        logger.info("WmsInventoryServiceImpl.updateStockNormal params:", JSONObject.toJSONString(freezeDTO));
        if (freezeDTO == null)
            throw new BusinessException("参数不能为空!");
        String whCode = freezeDTO.getWhCode();
        if (StringUtils.isBlank(whCode))
            throw new BusinessException("仓库code不能为空!");
        if (!(WhCodeEnum.JM_CS.getValue().equals(whCode) || WhCodeEnum.JM_XY.getValue().equals(whCode)))
            throw new BusinessException("该仓库不支持此操作!");
        String invlocIds = freezeDTO.getInvlocIds();
        if (StringUtils.isBlank(invlocIds))
            throw new BusinessException("请选择要冻结的车辆");
        String[] sp_ids = invlocIds.split(",");
        List<String> ids = Arrays.asList(sp_ids);
        List<WmsInventoryLocationFreezeDTO> list = wmsInventoryLocationExtMapper.selectFreezeListByIds(ids);
        StringBuilder cant_vin = new StringBuilder();
        list.forEach(v -> {
            if (StringUtils.isNotBlank(v.getPreparationVin())) {
                cant_vin.append(v.getPreparationVin()).append(",");
            }
        });
        if (StringUtils.isNotBlank(cant_vin)) {
            throw new BusinessException(cant_vin.substring(0, cant_vin.length() - 1) + "已经进行备料,不能进行释放!");
        }
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("normal_status", InventoryLocationStatusEnum.NORMAL_10.getCode());
        params.put("ids", ids);
        params.put("whCode", freezeDTO.getWhCode());
        wmsInventoryLocationExtMapper.updateNormalStatusByIds(params);
    }

    /**
     * 调整入库车辆的库位信息
     * <p>
     * 2018-4-10  新需求说明,增加调整入库车辆的库位信息(未出库确认之前都可以调整更换)
     * </p>
     *
     * @param dto 参数封装
     */
    @Override
    public void updateChangeLocCode(WmsInventoryChangeLocCodeDTO dto) {
        if (logger.isInfoEnabled()) {
            logger.info("WmsInventoryServiceImpl.updateChangeLocCode params:{}", JSONObject.toJSONString(dto));
        }
        if (dto == null)
            throw new BusinessException("传入的参数不能为空!");
        if (StringUtils.isBlank(dto.getWhCode()))
            throw new BusinessException("仓库code不能为空!");
        if (StringUtils.isBlank(dto.getInvlocCodeNew()))
            throw new BusinessException("传入的要更换的库位code不能为空!");
        if (StringUtils.isBlank(dto.getInvlocId()))
            throw new BusinessException("请选择要调整库位的数据");
        if (StringUtils.isBlank(dto.getInvlocVin()))
            throw new BusinessException("要调整的车辆车架号不能为空!");
        if (!(WhCodeEnum.JM_CS.getValue().equals(dto.getWhCode()) || WhCodeEnum.JM_XY.getValue().equals(dto.getWhCode()))) {
            throw new BusinessException("此操作不支持该仓库");
        }
        WmsInventoryLocation wmsInventoryLocation = wmsInventoryLocationMapper.selectByPrimaryKey(Long.valueOf(dto.getInvlocId()));
        if (InventoryLocationStatusEnum.MAINTAIN_LOCK_50.getCode().equals(wmsInventoryLocation.getStatus())) {
            throw new BusinessException("此车辆VIN:" + wmsInventoryLocation.getInvlocVin() + "已出库确认支持此操作!");
        }
        if (dto.getInvlocCodeNew().equals(wmsInventoryLocation.getInvlocLocCode())) {
            throw new BusinessException("替换的库位code与原库位code一致!");
        }
        //校验changecodenew可用性
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("whCode", dto.getWhCode());
        params.put("locNew", dto.getInvlocCodeNew());
        List<SelectChangeLocCodeFromGetLocationDTO> codes = wmsInventoryLocationExtMapper.selectChangeCodeNewFromGetLocation(params);
        if (CollectionUtils.isEmpty(codes))
            throw new BusinessException("此仓库CODE:" + dto.getInvlocCodeNew() + "不存在!");
        if (CollectionUtils.isNotEmpty(codes)) {
            if (codes.size() > 1) {
                throw new BusinessException("此仓库CODE:" + dto.getInvlocCodeNew() + "存在多条,请联系管理员处理!");
            }
            SelectChangeLocCodeFromGetLocationDTO code = codes.get(0);
            if (String.valueOf(DeleteFlagEnum.DELETED.getValue()).equals(code.getIsDeleted())) {
                throw new BusinessException("此仓库CODE:" + dto.getInvlocCodeNew() + "已删除,不能使用!");
            }
            if ("N".equals(code.getLocEnableFlag())) {
                throw new BusinessException("此仓库CODE:" + dto.getInvlocCodeNew() + "已禁用,请恢复!");
            }
            if (StringUtils.isBlank(code.getUsefulLocCode())) {
                //说明不可用
                WmsInventoryLocationExample example = new WmsInventoryLocationExample();
                example.createCriteria().andInvlocLocCodeEqualTo(dto.getInvlocCodeNew())
                        .andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue())
                        .andInvlocWhCodeEqualTo(dto.getWhCode());
                List<WmsInventoryLocation> locations = wmsInventoryLocationMapper.selectByExample(example);
                if (CollectionUtils.isNotEmpty(locations)) {
                    WmsInventoryLocation location = locations.get(0);
                    throw new BusinessException("此仓库CODE:" + dto.getInvlocCodeNew() +
                            "已经被VIN:" + location.getInvlocVin() + "占用,请重新选择");
                }
            }
            //更新order_detail
            //更新inbound_allocation
            //更新inventory_location
            params.put("vin", dto.getInvlocVin());
            params.put("zoneCodeNew", code.getLocZoneCode());
            params.put("zoneNameNew", code.getLocZoneName());
            params.put("locIdNew", code.getLocId());
            params.put("invlocId", dto.getInvlocId());
            wmsInventoryLocationExtMapper.updateInventoryLocCodeNew(params);
            //更新outbound_task
            WmsOutboundTaskExample taskExample = new WmsOutboundTaskExample();
            taskExample.createCriteria().andOtVinEqualTo(dto.getInvlocVin())
                    .andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue());
            taskExample.setOrderByClause("ot_id desc");
            taskExample.setLimitStart(0);
            taskExample.setLimitEnd(1);
            List<WmsOutboundTask> tasks = wmsOutboundTaskMapper.selectByExample(taskExample);
            if (CollectionUtils.isNotEmpty(tasks)) {
                WmsOutboundTask task = tasks.get(0);
                task.setOtLocationCode(dto.getInvlocCodeNew());
                task.setOtLcoationName(dto.getInvlocCodeNew());
                task.setOtZoneCode(code.getLocZoneCode());
                task.setOtZoneName(code.getLocZoneName());
                wmsOutboundTaskMapper.updateByPrimaryKeySelective(task);
            }
        }
    }


    /**
     * 获取所有的库存颜色编码和名称:
     *
     * @param wmsInventoryQueryDTO 仓库code参数封装
     * @return 返回值
     * @throws Exception 异常
     */
    @Override
    public List<WmsInventoryLocationExtDTO> selectColourListForJM(@RequestBody WmsInventoryQueryDTO wmsInventoryQueryDTO) throws Exception {
        logger.info("WmsInventoryServiceImpl.selectColourListForJM param:{}", JSONObject.toJSONString(wmsInventoryQueryDTO));
        if (wmsInventoryQueryDTO == null)
            throw new BusinessException("传入参数为空!");
        String invWhCode = wmsInventoryQueryDTO.getInvWhCode();
        if (StringUtils.isNotBlank(invWhCode) &&
                !(WhCodeEnum.JM_CS.getValue().equals(invWhCode) || WhCodeEnum.JM_XY.getValue().equals(invWhCode)))
            throw new BusinessException("该仓库不支持此操作!");
        Map<String, Object> paramMap = ObjectToMapUtils.objectToMap(wmsInventoryQueryDTO);
        //return wmsInventoryExtMapper.selectColourListForJMInventory(paramMap);
        return wmsInventoryExtMapper.selectColourListForJMInventoryWithNotice(paramMap);
    }

    @Override
    public List<WmsInventoryLocationExtDTO> selectMaterialListForJM(@RequestBody WmsInventoryQueryDTO wmsInventoryQueryDTO) throws Exception {
        logger.info("WmsInventoryServiceImpl.selectMaterialListForJM param:{}", JSONObject.toJSONString(wmsInventoryQueryDTO));
        if (wmsInventoryQueryDTO == null)
            throw new BusinessException("传入参数为空!");
        String invWhCode = wmsInventoryQueryDTO.getInvWhCode();
        if (StringUtils.isNotBlank(invWhCode) &&
                !(WhCodeEnum.JM_CS.getValue().equals(invWhCode) || WhCodeEnum.JM_XY.getValue().equals(invWhCode)))
            throw new BusinessException("该仓库不支持此操作!");
        Map<String, Object> paramMap = ObjectToMapUtils.objectToMap(wmsInventoryQueryDTO);
        //return wmsInventoryExtMapper.selectMaterialListForJMInventory(paramMap);
        return wmsInventoryExtMapper.selectMaterialListForJMInventoryWithNotice(paramMap);
    }


    @Override
    public void addInventory(WmsInboundCheckBO wmsInboundCheckBO) throws Exception {
        try {
            List<AsnOrderDTO> asnInfoList = wmsInboundAsnOrderAddMapper.queryAllAsnInfo(String.valueOf(wmsInboundCheckBO.getOdId()));
            if (CollectionUtils.isNotEmpty(asnInfoList)) {
                WmsInventory wmsInventory = new WmsInventory();
                wmsInventory.setInvVehicleBrandName(asnInfoList.get(0).getAsnOrderDetailDTOList().get(0).getOddVehicleBrandCode());
                wmsInventory.setInvVehicleBrandCode(asnInfoList.get(0).getAsnOrderDetailDTOList().get(0).getOddVehicleBrandName());
                wmsInventory.setInvVehicleSeriesCode(asnInfoList.get(0).getAsnOrderDetailDTOList().get(0).getOddVehicleSeriesCode());
                wmsInventory.setInvVehicleSeriesCode(asnInfoList.get(0).getAsnOrderDetailDTOList().get(0).getOddVehicleSeriesName());
                wmsInventory.setInvVehicleSpecCode(asnInfoList.get(0).getAsnOrderDetailDTOList().get(0).getOddVehicleSpecCode());
                wmsInventory.setInvVehicleSpecName(asnInfoList.get(0).getAsnOrderDetailDTOList().get(0).getOddVehicleSpecName());
                wmsInventory.setInvVehicleSpecDesc(asnInfoList.get(0).getAsnOrderDetailDTOList().get(0).getOddVehicleSpecDesc());
                wmsInventory.setIsDeleted((byte) 0);
                wmsInventoryExtMapper.insertInventory(wmsInventory);
                Long invId = wmsInventory.getInvId();

                //新增库存商品所在的库位信息
                WmsInventoryLocation wmsInventoryLocation = new WmsInventoryLocation();
                wmsInventoryLocation.setInvlocInvId(invId);
                /*wmsInventoryLocation.setInvlocWhId(wmsInboundCheckBO.getOdWhId());
                wmsInventoryLocation.setInvlocWhCode(wmsInboundCheckBO.getOdWhCode());
                wmsInventoryLocation.setInvlocWhName();
                wmsInventoryLocation.setInvlocWhType();*/
                wmsInventoryLocation.setInvlocCustomerCode(String.valueOf(asnInfoList.get(0).getOdCustomerCode() == null ? "" : asnInfoList.get(0).getOdCustomerCode()));
                wmsInventoryLocation.setInvlocVin(asnInfoList.get(0).getAsnOrderDetailDTOList().get(0).getOddVin());
                wmsInventoryLocation.setInvlocWaybillNo(asnInfoList.get(0).getOdWaybillNo());
                wmsInventoryLocation.setInvlocOdId(asnInfoList.get(0).getOdId());//订单ID
                wmsInventoryLocation.setInvlocZoneCode(asnInfoList.get(0).getAsnOrderDetailDTOList().get(0).getOddWhZoneCode());//库区code
                wmsInventoryLocation.setInvlocZoneName(asnInfoList.get(0).getAsnOrderDetailDTOList().get(0).getOddWhZoneCode());//库区
                wmsInventoryLocation.setInvlocLocCode(asnInfoList.get(0).getAsnOrderDetailDTOList().get(0).getOddWhLocCode());//库位code
                wmsInventoryLocation.setInvlocLocName(asnInfoList.get(0).getAsnOrderDetailDTOList().get(0).getOddWhLocCode());//库位
                wmsInventoryLocation.setIsDeleted((byte) 0);
                wmsInventoryLocationMapper.insert(wmsInventoryLocation);
            }
        } catch (Exception ex) {
            throw new Exception("数据库异常");
        }
    }

    /**
     * 根据物料编码和颜色和车型名字获取库存记录 - 根据批次号排序(降序)
     *
     * @param materialCode 物料编码
     * @param color        颜色
     * @param vehicleName  车型名称
     * @return 返回
     */
    @Override
    public List<WmsInventory> selectInvertoryListForPlan(String materialCode, String color, String vehicleName, String whCode) {
        if (StringUtils.isNotBlank(materialCode) && StringUtils.isNotBlank(color)
                && StringUtils.isNotBlank(vehicleName) && StringUtils.isNotBlank(whCode)) {

            WmsInventoryExample example = new WmsInventoryExample();
            WmsInventoryExample.Criteria criteria = example.createCriteria();
            criteria.andInvMaterialCodeEqualTo(materialCode);
            criteria.andInvVehicleSpecNameEqualTo(vehicleName);
            criteria.andInvColorEqualTo(color);
            criteria.andInvWhCodeEqualTo(whCode);
            criteria.andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue());
            return wmsInventoryMapper.selectByExample(example);
        }
        return null;
    }

    /**
     * 根据物料编码和颜色和车型名字获取库存记录 - 根据批次号排序(降序)--现在改成以code进行匹配
     *
     * @param materialCode 物料编码code
     * @param colorCode    颜色code
     * @param vehicleCode  车型code
     * @return 返回
     */
    @Override
    public List<WmsInventory> selectChangeVinForPlanNew(String materialCode, String colorCode, String vehicleCode, String whCode, String oldVin) {
        if (StringUtils.isNotBlank(materialCode) && StringUtils.isNotBlank(colorCode)
                && StringUtils.isNotBlank(vehicleCode) && StringUtils.isNotBlank(whCode)) {
            //bugfix 2018-3-6 在未进行任务的时候可能找到同一台车进行更换
            HashMap<String, Object> params = Maps.newHashMap();
            params.put("materialCode", materialCode);
            params.put("carColourCode", colorCode);
            params.put("vehicleCode", vehicleCode);
            params.put("notDel", DeleteFlagEnum.NORMAL.getValue());
            params.put("whCode", whCode);
            params.put("normalStatus", InventoryLocationStatusEnum.NORMAL_10.getCode());
            params.put("start", 0);
            params.put("end", 1);
            params.put("orderByClause", " b.invloc_lot asc, b.invloc_id asc ");
            params.put("oldVin", oldVin);
            return wmsInventoryExtMapper.selectChangeVinNewForJM(params);
        }
        return null;
    }

    /**
     * 根据物料编码和颜色和车型名字获取库存记录 - 根据批次号排序(降序)--现在改成以code进行匹配
     *
     * @param materialCode 物料编码code
     * @param colorCode    颜色code
     * @param vehicleCode  车型code
     * @return 返回
     */
    @Override
    public List<WmsInventory> selectInvertoryListForPlanNew(String materialCode,
                                                            String colorCode,
                                                            String vehicleCode,
                                                            String whCode) {
        if (StringUtils.isNotBlank(materialCode) && StringUtils.isNotBlank(colorCode)
                && StringUtils.isNotBlank(vehicleCode) && StringUtils.isNotBlank(whCode)) {
            WmsInventoryExample example = new WmsInventoryExample();
            WmsInventoryExample.Criteria criteria = example.createCriteria();
            criteria.andInvMaterialCodeEqualTo(materialCode);
            //criteria.andInvCarColourCodeEqualTo(colorCode);
            //criteria.andInvVehicleSpecNameEqualTo(vehicleCode);
            criteria.andInvWhCodeEqualTo(whCode);
            criteria.andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue());
            return wmsInventoryMapper.selectByExample(example);
        }
        return null;
    }


    /**
     * 查询库存明细 -  根据批次号排序(降序) 正常在库的
     */
    @Override
    public List<WmsInventoryLocation> listInventoryLocation(List<Long> invIdList, String whCode) {
        if (CollectionUtils.isNotEmpty(invIdList) && StringUtils.isNotBlank(whCode)) {

            WmsInventoryLocationExample example = new WmsInventoryLocationExample();
            example.setOrderByClause(" invloc_lot asc, invloc_id asc ");
            WmsInventoryLocationExample.Criteria criteria = example.createCriteria();
            criteria.andInvlocInvIdIn(invIdList);
            criteria.andInvlocWhCodeEqualTo(whCode);
            criteria.andInvlocLotIsNotNull();
            criteria.andStatusEqualTo(InventoryLocationStatusEnum.NORMAL_10.getCode());//正常在库
            criteria.andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue());
            return wmsInventoryLocationMapper.selectByExample(example);
        }
        return null;
    }

    @Override
    public Integer countInventoryLocation(List<Long> invIdList, String whCode) {
        if (CollectionUtils.isNotEmpty(invIdList) && StringUtils.isNotBlank(whCode)) {

            WmsInventoryLocationExample example = new WmsInventoryLocationExample();
            example.setOrderByClause(" invloc_lot asc, invloc_id asc ");
            WmsInventoryLocationExample.Criteria criteria = example.createCriteria();
            criteria.andInvlocInvIdIn(invIdList);
            criteria.andInvlocWhCodeEqualTo(whCode);
            criteria.andInvlocLotIsNotNull();
            criteria.andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue());
            return wmsInventoryLocationMapper.countByExample(example);
        }
        return null;
    }

    /**
     * 查询正常状态 - 批次号不为空的
     */
    @Override
    public List<WmsInventoryLocation> listInventoryLocationForNormal(List<Long> invIdList, String whCode, int count) {
        if (CollectionUtils.isNotEmpty(invIdList) && StringUtils.isNotBlank(whCode)) {

            WmsInventoryLocationExample example = new WmsInventoryLocationExample();
            example.setOrderByClause(" invloc_lot asc, invloc_id asc ");
            example.setLimitStart(0);
            example.setLimitEnd(count);
            WmsInventoryLocationExample.Criteria criteria = example.createCriteria();
            criteria.andInvlocInvIdIn(invIdList);
            criteria.andInvlocWhCodeEqualTo(whCode);
            criteria.andInvlocLotIsNotNull();
            criteria.andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue());//正常状态
            criteria.andStatusEqualTo(InventoryLocationStatusEnum.NORMAL_10.getCode());//正常状态
            return wmsInventoryLocationMapper.selectByExample(example);
        }
        return null;
    }

    /**
     * 查询正常状态 - 批次号为空的, 创建时间降序
     */
    @Override
    public List<WmsInventoryLocation> listInventoryLocationForNormalBatchNoIsNull(List<Long> invIdList, String whCode, int count) {
        if (CollectionUtils.isNotEmpty(invIdList) && StringUtils.isNotBlank(whCode)) {

            WmsInventoryLocationExample example = new WmsInventoryLocationExample();
            example.setOrderByClause(" gmt_create asc, invloc_id asc ");
            example.setLimitStart(0);
            example.setLimitEnd(count);

            WmsInventoryLocationExample.Criteria criteria = example.createCriteria();
            criteria.andInvlocInvIdIn(invIdList);
            criteria.andInvlocWhCodeEqualTo(whCode);
            criteria.andInvlocLotIsNull();
            criteria.andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue());//正常状态
            criteria.andStatusEqualTo(InventoryLocationStatusEnum.NORMAL_10.getCode());//正常状态
            return wmsInventoryLocationMapper.selectByExample(example);
        }
        return null;
    }

    /**
     * 获取数量
     */
    @Override
    public Integer countInventoryLocationForNormal(List<Long> invIdList, String whCode, int count) {
        if (CollectionUtils.isNotEmpty(invIdList) && StringUtils.isNotBlank(whCode)) {

            WmsInventoryLocationExample example = new WmsInventoryLocationExample();
            example.setOrderByClause(" invloc_lot asc, invloc_id asc ");
            example.setLimitStart(0);
            example.setLimitEnd(count);
            WmsInventoryLocationExample.Criteria criteria = example.createCriteria();
            criteria.andInvlocInvIdIn(invIdList);
            criteria.andInvlocWhCodeEqualTo(whCode);
            criteria.andInvlocLotIsNotNull();
            criteria.andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue());//正常状态
            criteria.andStatusEqualTo(InventoryLocationStatusEnum.NORMAL_10.getCode());//正常状态
            return wmsInventoryLocationMapper.countByExample(example);
        }
        return null;
    }

    /**
     * 批量逻辑删除
     */
    @Override
    public void deleteInventoryForBatch(List<Long> idList) {

        WmsInventoryExample example = new WmsInventoryExample();
        example.createCriteria().andInvIdIn(idList);

        WmsInventory updateInventory = new WmsInventory();
        updateInventory.setIsDeleted(DeleteFlagEnum.DELETED.getValue());

        wmsInventoryMapper.updateByExampleSelective(updateInventory, example);
    }

    /**
     * 批量逻辑删除
     */
    @Override
    public void deleteLocationForBatch(List<Long> idList) {

        WmsInventoryLocationExample example = new WmsInventoryLocationExample();
        example.createCriteria().andInvlocIdIn(idList);

        WmsInventoryLocation updateLocation = new WmsInventoryLocation();
        updateLocation.setIsDeleted(DeleteFlagEnum.DELETED.getValue());

        wmsInventoryLocationMapper.updateByExampleSelective(updateLocation, example);
    }

    /**
     * 根据主键集合批量更新状态
     */
    @Override
    public void updateStatusLocationForBatch(List<Long> idList, String status) {
        if (CollectionUtils.isNotEmpty(idList) && StringUtils.isNotBlank(status)) {
            WmsInventoryLocationExample example = new WmsInventoryLocationExample();
            example.createCriteria().andInvlocIdIn(idList);

            WmsInventoryLocation updateLocation = new WmsInventoryLocation();
            updateLocation.setStatus(status);

            wmsInventoryLocationMapper.updateByExampleSelective(updateLocation, example);
        }
    }

    /**
     * 根据主键更新状态
     */
    @Override
    public void updateStatusLocation(Long id, String status) {
        if (StringUtils.isNotBlank(status) && id != null) {
            WmsInventoryLocation updateLocation = new WmsInventoryLocation();
            updateLocation.setInvlocId(id);
            updateLocation.setStatus(status);
            wmsInventoryLocationMapper.updateByPrimaryKeySelective(updateLocation);
        }
    }

    /**
     * 根据车架号修改状态
     */
    @Override
    public boolean updateStatusLocationByVin(String vin, String status) {
        boolean resultBoolean = false;
        if (StringUtils.isNotBlank(vin) && StringUtils.isNotBlank(status)) {
            WmsInventoryLocationExample locationExample = new WmsInventoryLocationExample();
            locationExample.setOrderByClause("invloc_id desc");
            locationExample.createCriteria().andInvlocVinEqualTo(vin);
            List<WmsInventoryLocation> wmsInventoryLocations = wmsInventoryLocationMapper.selectByExample(locationExample);
            if (CollectionUtils.isNotEmpty(wmsInventoryLocations)) {
                WmsInventoryLocation updateLocation = wmsInventoryLocations.get(0);
                updateLocation.setStatus(status);
                updateLocation.setIsDeleted(DeleteFlagEnum.DELETED.getValue());
                wmsInventoryLocationMapper.updateByPrimaryKeySelective(updateLocation);
                resultBoolean = true;
            }
        }
        return resultBoolean;
    }

    /**
     * 获取库位信息
     */
    @Override
    public WmsInventoryLocation getInventoryLocationByVin(String vin) {
        if (StringUtils.isNotBlank(vin)) {
            WmsInventoryLocationExample locationExample = new WmsInventoryLocationExample();
            locationExample.setOrderByClause("invloc_id desc");
            locationExample.createCriteria().andInvlocVinEqualTo(vin);
            List<WmsInventoryLocation> wmsInventoryLocations = wmsInventoryLocationMapper.selectByExample(locationExample);
            if (CollectionUtils.isNotEmpty(wmsInventoryLocations)) {
                return wmsInventoryLocations.get(0);
            }
        }
        return null;
    }

    /**
     * 根据主表主键获取数据
     */
    @Override
    public WmsInventoryLocation getInventoryLocationByParentId(Long id) {
        WmsInventoryLocationExample example = new WmsInventoryLocationExample();
        example.createCriteria().andInvlocInvIdEqualTo(id);
        List<WmsInventoryLocation> inventoryLocationList = wmsInventoryLocationMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(inventoryLocationList)) {
            return inventoryLocationList.get(0);
        }
        return null;
    }

    /**
     * 根据库存查询记录
     */
    @Override
    public List<WmsInventoryLocation> getLocationByVin(String vin) {
        if (StringUtils.isNotBlank(vin)) {
            WmsInventoryLocationExample example = new WmsInventoryLocationExample();
            example.createCriteria().andInvlocVinEqualTo(vin);
            return wmsInventoryLocationMapper.selectByExample(example);
        }
        return null;
    }

    @Override
    public WmsInventory getWmsInventoryByPrimaryKey(Long id) {
        if (id != null) {
            return wmsInventoryMapper.selectByPrimaryKey(id);
        }
        return null;
    }

    public List<InvoicingStatisticsChartDataDTO> invoicingStatisticsChartCount() {
        List<InvoicingStatisticsChartDataDTO> invoicingStatisticsDataDTOList = new ArrayList<InvoicingStatisticsChartDataDTO>();

        InvoicingStatisticsChartDataDTO invoicingStatisticsChartDataDTO1 = new InvoicingStatisticsChartDataDTO();
        InvoicingStatisticsChartDataDTO invoicingStatisticsChartDataDTO2 = new InvoicingStatisticsChartDataDTO();
        InvoicingStatisticsChartDataDTO invoicingStatisticsChartDataDTO3 = new InvoicingStatisticsChartDataDTO();

        invoicingStatisticsChartDataDTO1.setName("入库");
        invoicingStatisticsChartDataDTO2.setName("发运");
        invoicingStatisticsChartDataDTO3.setName("库存");

        invoicingStatisticsChartDataDTO1.setData(getNearFiveInboundNum(5));
        invoicingStatisticsChartDataDTO2.setData(getNearFourShipmentNumNew(5));
        invoicingStatisticsChartDataDTO3.setData(getInventoryNum(5));

        invoicingStatisticsChartDataDTO1.setDate(TimeUtil.getBeforeDates2(5));
        invoicingStatisticsChartDataDTO2.setDate(TimeUtil.getBeforeDates2(5));
        invoicingStatisticsChartDataDTO3.setDate(TimeUtil.getBeforeDates2(5));

        invoicingStatisticsDataDTOList.add(invoicingStatisticsChartDataDTO1);
        invoicingStatisticsDataDTOList.add(invoicingStatisticsChartDataDTO2);
        invoicingStatisticsDataDTOList.add(invoicingStatisticsChartDataDTO3);

        return invoicingStatisticsDataDTOList;
    }

    private Integer[] getNearFiveInboundNum(Integer num) {
        // 入库数量数组
        Integer[] nums = new Integer[num];

        int i = 0;
        for (num = num; num > 0; num--) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, -num);
            BiInOutInventoryChartExample biInOutInventoryChartExample = new BiInOutInventoryChartExample();
            biInOutInventoryChartExample.createCriteria().andDateEqualTo(calendar.getTime());
            List<BiInOutInventoryChart> biInOutInventoryChartList = biInOutInventoryChartMapper.selectByExample(biInOutInventoryChartExample);
            if (CollectionUtils.isEmpty(biInOutInventoryChartList)) {
                nums[i] = 0;
            } else {
                BiInOutInventoryChart biInOutInventoryChart = biInOutInventoryChartList.get(0);
                nums[i] = biInOutInventoryChart.getInNum();
            }
            i++;
        }

//        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//        String startTime   = null;
//        String endTime     = null;
//        Integer inboundNum = 0;
//
//        int i = 0;
//        for (num=num; num>0; num--) {
//            startTime = TimeUtil.getStartTime(num);
//            endTime   = TimeUtil.getEndTime(num);
//            inboundNum = wmsInventoryExtMapper.selectInboundNum(startTime, endTime);
//            nums [i] = inboundNum;
//            i ++ ;
//        }

        return nums;
    }


    @Autowired
    private BiDistributionHeadExtMapper distributionHeadExtMapper;

    /**
     * 统计发运数
     *
     * @param num 初始化数据
     * @return 返回值
     */
    private Integer[] getNearFourShipmentNumNew(Integer num) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<BiDistributionHead> biDistributionHeads = distributionHeadExtMapper.distributionChartCount();
        Integer[] nums = null;
        if (CollectionUtils.isNotEmpty(biDistributionHeads)) {
            nums = new Integer[num];
            for (BiDistributionHead next : biDistributionHeads) {
                Date shippingTime = next.getShippingTime();
                String sp_str = sdf.format(shippingTime);
                // 入库数量数组
                for (int i = num; i > 0; i--) {
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(new Date());
                    calendar.add(Calendar.DAY_OF_YEAR, -i);
                    Date time = calendar.getTime();
                    String f_time = sdf.format(time);
                    if (sp_str.contains(f_time)) {
                        if (Objects.equals(next.getNumberHair(), null)) {
                            nums[num - i] = 0;
                        } else {
                            nums[num - i] = next.getNumberHair();
                        }
                    }
                }
            }
        }
        return nums;
    }


    private Integer[] getNearFourShipmentNum(Integer num) {
        // 入库数量数组
        Integer[] nums = new Integer[num];

        int i = 0;
        for (num = num; num > 0; num--) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, -num);
            BiInOutInventoryChartExample biInOutInventoryChartExample = new BiInOutInventoryChartExample();
            biInOutInventoryChartExample.createCriteria().andDateEqualTo(calendar.getTime());
            List<BiInOutInventoryChart> biInOutInventoryChartList = biInOutInventoryChartMapper.selectByExample(biInOutInventoryChartExample);
            if (CollectionUtils.isEmpty(biInOutInventoryChartList)) {
                nums[i] = 0;
            } else {
                BiInOutInventoryChart biInOutInventoryChart = biInOutInventoryChartList.get(0);
                nums[i] = biInOutInventoryChart.getShipmentNum();
            }
            i++;
        }

//        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//        String startTime   = null;
//        String endTime     = null;
//        Integer inboundNum = 0;
//
//        int i = 0;
//        for (num=num; num>0; num--) {
//            startTime = TimeUtil.getStartTime(num);
//            endTime   = TimeUtil.getEndTime(num);
//            inboundNum = wmsOutboundTaskExtMapper.selectOutboundNum(startTime, endTime);
//            nums [i] = inboundNum;
//            i ++ ;
//        }

        return nums;
    }


    private Integer[] getInventoryNum(Integer num) {
        // 库存数量数组
        Integer[] nums = new Integer[num];

        int i = 0;
        for (num = num; num > 0; num--) {
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            calendar.add(Calendar.DATE, -num);
            BiInOutInventoryChartExample biInOutInventoryChartExample = new BiInOutInventoryChartExample();
            biInOutInventoryChartExample.createCriteria().andDateEqualTo(calendar.getTime());
            List<BiInOutInventoryChart> biInOutInventoryChartList = biInOutInventoryChartMapper.selectByExample(biInOutInventoryChartExample);
            if (CollectionUtils.isEmpty(biInOutInventoryChartList)) {
                nums[i] = 0;
            } else {
                BiInOutInventoryChart biInOutInventoryChart = biInOutInventoryChartList.get(0);
                nums[i] = biInOutInventoryChart.getInventoryNum();
            }
            i++;
        }
//        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//        String endTime     = null;
//        Integer inventoryNum = 0;
//
//        int i = 0;
//        for (num=num; num>0; num--) {
//            endTime   = TimeUtil.getEndTime(num);
//            inventoryNum = wmsInventoryExtMapper.selectInventoryNum(endTime);
//            nums [i] = inventoryNum;
//            i ++ ;
//        }

        return nums;
    }

    @Override
    public InvoicingStatisticsLineDataDTO invoicingStatisticsLineCount() {
        // 返回前端的对象
        InvoicingStatisticsLineDataDTO invoicingStatisticsLineDataDTO = new InvoicingStatisticsLineDataDTO();
        // 统计数据的body
        InvoicingStatisticsLineBody[] invoicingStatisticsLineBodys = new InvoicingStatisticsLineBody[4];

        // 查询已存放0到10天的库存
        List<InvoicingStatisticsDTO> invoicingStatisticsDTOList1 = wmsInventoryExtMapper.invoicingStatistics(0, 10);
        // 查询已存放11到30天的库存
        List<InvoicingStatisticsDTO> invoicingStatisticsDTOList2 = wmsInventoryExtMapper.invoicingStatistics(10, 30);
        // 查询已存放31到60天的库存
        List<InvoicingStatisticsDTO> invoicingStatisticsDTOList3 = wmsInventoryExtMapper.invoicingStatistics(30, 60);
        // 查询已存放60天以上的库存
        List<InvoicingStatisticsDTO> invoicingStatisticsDTOList4 = wmsInventoryExtMapper.invoicingStatistics(60, null);

        // 获取表头
        List<String> headList = new ArrayList<>();
        stuffHeadList(invoicingStatisticsDTOList1, headList);
        stuffHeadList(invoicingStatisticsDTOList2, headList);
        stuffHeadList(invoicingStatisticsDTOList3, headList);
        stuffHeadList(invoicingStatisticsDTOList4, headList);

        if (CollectionUtils.isEmpty(headList))
            throw new BusinessException("未查询到对应的数据信息");

        // 获取对应区间body数据
        Integer body1[] = new Integer[headList.size()];
        Integer body2[] = new Integer[headList.size()];
        Integer body3[] = new Integer[headList.size()];
        Integer body4[] = new Integer[headList.size()];
        setBodyValue(invoicingStatisticsDTOList1, headList, body1);
        setBodyValue(invoicingStatisticsDTOList2, headList, body2);
        setBodyValue(invoicingStatisticsDTOList3, headList, body3);
        setBodyValue(invoicingStatisticsDTOList4, headList, body4);
        InvoicingStatisticsLineBody invoicingStatisticsLineBody1 = new InvoicingStatisticsLineBody();
        invoicingStatisticsLineBody1.setName("1到10天");
        invoicingStatisticsLineBody1.setData(body1);

        InvoicingStatisticsLineBody invoicingStatisticsLineBody2 = new InvoicingStatisticsLineBody();
        invoicingStatisticsLineBody2.setName("11到30天");
        invoicingStatisticsLineBody2.setData(body2);

        InvoicingStatisticsLineBody invoicingStatisticsLineBody3 = new InvoicingStatisticsLineBody();
        invoicingStatisticsLineBody3.setName("31到60天");
        invoicingStatisticsLineBody3.setData(body3);

        InvoicingStatisticsLineBody invoicingStatisticsLineBody4 = new InvoicingStatisticsLineBody();
        invoicingStatisticsLineBody4.setName("60天以上天");
        invoicingStatisticsLineBody4.setData(body4);

        invoicingStatisticsLineBodys[0] = invoicingStatisticsLineBody1;
        invoicingStatisticsLineBodys[1] = invoicingStatisticsLineBody2;
        invoicingStatisticsLineBodys[2] = invoicingStatisticsLineBody3;
        invoicingStatisticsLineBodys[3] = invoicingStatisticsLineBody4;

        invoicingStatisticsLineDataDTO.setHead(headList);
        invoicingStatisticsLineDataDTO.setInvoicingStatisticsLineBody(invoicingStatisticsLineBodys);

        return invoicingStatisticsLineDataDTO;
    }

    /**
     * 设对应车型对应时间段
     *
     * @param invoicingStatisticsDTOList_i 结果集
     * @param headList                     头
     * @param body_i                       值
     */
    private void setBodyValue(List<InvoicingStatisticsDTO> invoicingStatisticsDTOList_i, List<String> headList, Integer[] body_i) {
        for (int i = 0; i < headList.size(); i++) {
            int finalI = i;
            String head = headList.get(finalI);
            invoicingStatisticsDTOList_i.forEach(dto -> {
                if (StringUtils.isNotBlank(dto.getVehicleType()) && head.equals(dto.getVehicleType())) {
                    if (dto.getNum() != null) {
                        body_i[finalI] = dto.getNum();
                    } else {
                        body_i[finalI] = 0;
                    }
                }
            });
        }
        //去掉null值
        for (int i = 0; i < body_i.length; i++) {
            if (body_i[i] == null) {
                body_i[i] = 0;
            }
        }
    }

    /**
     * 填充车型的表头
     *
     * @param invoicingStatisticsDTOList 参数封装
     * @param headList                   车型头
     */
    private void stuffHeadList(List<InvoicingStatisticsDTO> invoicingStatisticsDTOList, List<String> headList) {
        invoicingStatisticsDTOList.stream()
                .filter(dto -> dto != null && StringUtils.isNotBlank(dto.getVehicleType()))
                .forEach(dto -> {
                    if (!headList.contains(dto.getVehicleType())) {
                        headList.add(dto.getVehicleType());
                    }
                });
    }

    @Override
    public void addinvoicingStatisticsChart() {
        SimpleDateFormat simp1 = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat simp2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        // 获取当前天起始时间
        String startDate = simp1.format(new Date()) + " 00:00:00";
        // 获取当前天截至时间
        String endDate = simp2.format(new Date());

        BiInOutInventoryChart biInOutInventoryChart = new BiInOutInventoryChart();
        biInOutInventoryChart.setType(2);
        biInOutInventoryChart.setDate(new Date());
        // 保存当天入库数
        Integer inboundNum = wmsInventoryExtMapper.selectInboundNum(startDate, endDate);
        logger.info("当天入库数：" + inboundNum);
        biInOutInventoryChart.setInNum(inboundNum);
        // 保存当天发运数--已开闸数据算作是发运
        // bugfix--闸门未使用统计发运数
        Integer outboundNum = wmsOutboundTaskExtMapper.selectOutboundNum(startDate, endDate);
        logger.info("当天发运数：" + outboundNum);
        biInOutInventoryChart.setShipmentNum(outboundNum);
        // 保存当天的库存数---为开闸之前的也算做库存数
        Integer inventoryNum = wmsInventoryExtMapper.selectInventoryNum(endDate);
        //Integer notGateOutNum = wmsInventoryExtMapper.selectNotGateOutNumNum(endDate);
        //logger.info("截至库存数：" + (inventoryNum + notGateOutNum));
        //biInOutInventoryChart.setInventoryNum(inventoryNum + notGateOutNum);
        //Integer notGateOutNum = wmsInventoryExtMapper.selectNotGateOutNumNum(endDate);
        //logger.info("截至库存数：" + (inventoryNum + notGateOutNum));
        biInOutInventoryChart.setInventoryNum(inventoryNum);
        biInOutInventoryChartMapper.insertSelective(biInOutInventoryChart);
    }

    /**
     * 西南库存数据导出
     */
    @Override
    public HSSFWorkbook inventoryRecordImportForCq(WmsInventoryQueryDTO wmsInventoryQueryDTO) throws Exception {
        logger.info("WmsInventoryServiceImpl.inventoryRecordImportForCq param: {}", wmsInventoryQueryDTO);
        Map<String, Object> paramMap = ObjectToMapUtils.objectToMap(wmsInventoryQueryDTO);
        List<WmsInventoryDTO> wmsInventoryDTOList = wmsInventoryExtMapper.queryInventoryListForCqImport(paramMap);
        if (CollectionUtils.isEmpty(wmsInventoryDTOList)) {
            throw new BusinessException("没有对应的库存数据");
        }
        //1.导出excel头
        String[] hearders = new String[]{"货主", "车架号(VIN码)", "库区", "库位", "仓库代码", "仓库名称", "车型", "车型描述"};
        //设置值
        return updateExportToExcelForCq("库存记录数据导出", hearders, wmsInventoryDTOList, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 君马库存数据导出
     * <p>
     * 2018-1-23
     * 库存查询页面增加“物料代码”、“物料名称”、“颜色代码”、“颜色”字段显示，导出的文件中也需要包含这四个字段
     * 查询条件中增加“物料名称”、“颜色”、“库存状态”
     * 2018-4-23 因入库通知单重构,重写sql方法
     * </p>
     *
     * @param wmsInventoryQueryDTO 参数封装
     * @throws Exception 异常
     */
    @Override
    public HSSFWorkbook inventoryRecordImportForJm(WmsInventoryQueryDTO wmsInventoryQueryDTO) throws Exception {
        logger.info("WmsInventoryServiceImpl.inventoryRecordImportForJm param: {}", wmsInventoryQueryDTO);
        Map<String, Object> paramMap = ObjectToMapUtils.objectToMap(wmsInventoryQueryDTO);
        //List<WmsInventoryLocationExtDTO> locationExtDTOList = wmsInventoryExtMapper.queryInventoryListForJmImport(paramMap);
        List<WmsInventoryLocationExtDTO> locationExtDTOList = wmsInventoryExtMapper.queryInventoryListForJmImportWithNotice(paramMap);
        //计算库龄
        DateTimeFormatter format = DateTimeFormat.forPattern(DateUtils.YYYY_MM_DD);
        DateTime nowDate = new DateTime();
        if (CollectionUtils.isNotEmpty(locationExtDTOList)) {
            locationExtDTOList.stream()
                    .filter(dto -> dto != null && dto.getGmtCreate() != null)
                    .forEach(dto -> {
                        DateTime gmtCreate = new DateTime(dto.getGmtCreate());//入库时间
                        DateTime startTime = DateTime.parse(gmtCreate.toString(DateUtils.YYYY_MM_DD), format);

                        DateTime endTime = DateTime.parse(nowDate.toString(DateUtils.YYYY_MM_DD), format);
                        int days = Days.daysBetween(startTime, endTime).getDays();
                        if (days >= 0) {
                            dto.setWarehouseAge(days + 1);
                        }
                    });
        }
        if (CollectionUtils.isEmpty(locationExtDTOList)) {
            throw new BusinessException("没有对应的库存数据");
        }
        //1.导出excel头
        String[] hearders = new String[]{"货主", "车架号(VIN码)", "车型", "物料编码", "物料名称", "颜色编码", "颜色名称"
                , "生产日期", "下线日期", "入库日期", "在库库龄", "库存状态", "库区", "库位", "仓库代码", "仓库名称"};
        //设置值
        return updateExportToExcelForJm("库存记录数据导出", hearders, locationExtDTOList, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 库存数据导出判断
     *
     * @param wmsInventoryQueryDTO 参数封装
     * @return 返回值
     * @throws Exception 异常
     */
    @Override
    public Integer countInventoryRecord(WmsInventoryQueryDTO wmsInventoryQueryDTO) throws Exception {
        Map<String, Object> paramMap = ObjectToMapUtils.objectToMap(wmsInventoryQueryDTO);
        if (WarehouseEnum.UNLCN_XN_CQ.getWhCode().equals(wmsInventoryQueryDTO.getInvWhCode())) {
            //西南库存数据导出
            return wmsInventoryExtMapper.countInventoryCountForCq(paramMap);
        } else if (WarehouseEnum.JM_CS.getWhCode().equals(wmsInventoryQueryDTO.getInvWhCode())
                || WarehouseEnum.JM_XY.getWhCode().equals(wmsInventoryQueryDTO.getInvWhCode())) {
            //君马库存数据导出
            return wmsInventoryExtMapper.countInventoryCountForJmWithNotice(paramMap);
        }
        return null;
    }


    /**
     * 生成表格并填充数据 - 西南
     *
     * @param title               标题
     * @param headers             表头
     * @param wmsInventoryDTOList 列表
     * @param pattern             时间格式
     * @return 返回值
     */
    private HSSFWorkbook updateExportToExcelForCq(String title, String[] headers,
                                                  List<WmsInventoryDTO> wmsInventoryDTOList,
                                                  String pattern) {
        // 声明一个工作薄
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 生成一个表格
        HSSFSheet sheet = workbook.createSheet(title);
        // 设置表格默认列宽度为15个字节
        sheet.setDefaultColumnWidth((short) 20);
        HSSFCellStyle titleStyle = workbook.createCellStyle();
        HSSFCellStyle cellStyle = workbook.createCellStyle();
        // 产生表格标题行
        HSSFRow row = sheet.createRow(0);
        //初始化表格设置
        initExcelSet(workbook, titleStyle, cellStyle, row, headers);
        for (int i = 0; i < wmsInventoryDTOList.size(); i++) {
            row = sheet.createRow(i + 1);//创建行
            WmsInventoryDTO wmsInventoryDTO = wmsInventoryDTOList.get(i);
            WmsInventoryLocationDTO wmsInventoryLocationDTO = null;
            if (wmsInventoryDTO != null) {
                List<WmsInventoryLocationDTO> wmsInventoryLocationDTOList = wmsInventoryDTO.getWmsInventoryLocationDTOList();
                if (CollectionUtils.isNotEmpty(wmsInventoryLocationDTOList) && wmsInventoryLocationDTOList.get(0) != null) {
                    wmsInventoryLocationDTO = wmsInventoryLocationDTOList.get(0);
                }
                if (wmsInventoryLocationDTO != null) {
                    for (int k = 0; k < headers.length; k++) {
                        HSSFCell cell = row.createCell(k);
                        cell.setCellStyle(cellStyle);
                        //"货主", "车架号(VIN码)", "库区", "库位", "仓库代码", "仓库名称", "车型", "车型描述"
                        switch (k) {
                            case 0: {
                                cell.setCellValue(updateSetCellValue(wmsInventoryDTO.getInvCustomerName()));
                                break;
                            }
                            case 1: {
                                //车架号
                                cell.setCellValue(updateSetCellValue(wmsInventoryLocationDTO.getInvlocVin()));
                                break;
                            }
                            case 2: {
                                //库区
                                cell.setCellValue(updateSetCellValue(wmsInventoryLocationDTO.getInvlocZoneName()));
                                break;
                            }
                            case 3: {
                                //库位
                                cell.setCellValue(updateSetCellValue(wmsInventoryLocationDTO.getInvlocLocCode()));
                                break;
                            }
                            case 4: {
                                //仓库代码
                                cell.setCellValue(updateSetCellValue(wmsInventoryDTO.getInvWhCode()));
                                break;
                            }
                            case 5: {
                                //仓库名称
                                cell.setCellValue(updateSetCellValue(wmsInventoryDTO.getInvWhName()));
                                break;
                            }
                            case 6: {
                                //车型
                                cell.setCellValue(updateSetCellValue(wmsInventoryDTO.getInvVehicleSpecName()));
                                break;
                            }
                            case 7: {
                                //车型描述
                                cell.setCellValue(updateSetCellValue(wmsInventoryDTO.getInvVehicleSpecDesc()));
                                break;
                            }
                        }
                    }
                }
            }
        }
        return workbook;
    }

    /**
     * 生成表格并填充数据 - 君马
     *
     * @param title              标题
     * @param headers            表头
     * @param locationExtDTOList 列表
     * @param pattern            时间格式
     * @return 返回值
     */
    private HSSFWorkbook updateExportToExcelForJm(String title, String[] headers,
                                                  List<WmsInventoryLocationExtDTO> locationExtDTOList,
                                                  String pattern) {
        // 声明一个工作薄
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 生成一个表格
        HSSFSheet sheet = workbook.createSheet(title);
        // 设置表格默认列宽度为15个字节
        sheet.setDefaultColumnWidth((short) 20);
        HSSFCellStyle titleStyle = workbook.createCellStyle();
        HSSFCellStyle cellStyle = workbook.createCellStyle();
        // 产生表格标题行
        HSSFRow row = sheet.createRow(0);
        //初始化表格设置
        initExcelSet(workbook, titleStyle, cellStyle, row, headers);
        for (int i = 0; i < locationExtDTOList.size(); i++) {
            row = sheet.createRow(i + 1);//创建行
            WmsInventoryLocationExtDTO wmsInventoryLocationExtDTO = locationExtDTOList.get(i);
            if (wmsInventoryLocationExtDTO != null) {
                for (int k = 0; k < headers.length; k++) {
                    HSSFCell cell = row.createCell(k);
                    cell.setCellStyle(cellStyle);
                    //"货主", "车架号(VIN码)", "车型", "物料编码", "物料名称", "颜色编码", "颜色名称"
                    //, "生产日期", "下线日期", "入库日期", "在库库龄","库存状态", "库区", "库位", "仓库代码", "仓库名称"
                    switch (k) {
                        case 0: {
                            cell.setCellValue(updateSetCellValue(wmsInventoryLocationExtDTO.getInvCustomerName()));
                            break;
                        }
                        case 1: {
                            //车架号
                            cell.setCellValue(updateSetCellValue(wmsInventoryLocationExtDTO.getInvlocVin()));
                            break;
                        }
                        case 2: {
                            //车型
                            cell.setCellValue(updateSetCellValue(wmsInventoryLocationExtDTO.getInvVehicleSpecName()));
                            break;
                        }
                        case 3: {
                            //物料编码
                            cell.setCellValue(updateSetCellValue(wmsInventoryLocationExtDTO.getMaterialCode()));
                            break;
                        }
                        case 4: {
                            //物料名称
                            cell.setCellValue(updateSetCellValue(wmsInventoryLocationExtDTO.getMaterialName()));
                            break;
                        }
                        case 5: {
                            //颜色编码
                            cell.setCellValue(updateSetCellValue(wmsInventoryLocationExtDTO.getColourCode()));
                            break;
                        }
                        case 6: {
                            //颜色名称
                            cell.setCellValue(updateSetCellValue(wmsInventoryLocationExtDTO.getColourName()));
                            break;
                        }
                        case 7: {
                            //生产日期
                            cell.setCellValue(updateSetCellValue(DateUtils.getStringFromDate(wmsInventoryLocationExtDTO.getAtProductionDate(),
                                    DateUtils.FORMAT_DATETIME)));
                            break;
                        }
                        case 8: {
                            //下线日期
                            cell.setCellValue(updateSetCellValue(DateUtils.getStringFromDate(wmsInventoryLocationExtDTO.getAtOfflineDate(),
                                    DateUtils.FORMAT_DATETIME)));
                            break;
                        }
                        case 9: {
                            //入库日期
                            cell.setCellValue(updateSetCellValue(DateUtils.getStringFromDate(wmsInventoryLocationExtDTO.getGmtCreate(),
                                    DateUtils.FORMAT_DATETIME)));
                            break;
                        }
                        case 10: {
                            //在库库龄
                            cell.setCellValue(updateSetCellValue(wmsInventoryLocationExtDTO.getWarehouseAge()));
                            break;
                        }
                        case 11: {
                            //库存状态
                            cell.setCellValue(updateSetCellValue(wmsInventoryLocationExtDTO.getStatus()));
                            break;
                        }
                        case 12: {
                            //库区
                            cell.setCellValue(updateSetCellValue(wmsInventoryLocationExtDTO.getInvlocZoneName()));
                            break;
                        }
                        case 13: {
                            //库位
                            cell.setCellValue(updateSetCellValue(wmsInventoryLocationExtDTO.getInvlocLocCode()));
                            break;
                        }
                        case 14: {
                            //仓库代码
                            cell.setCellValue(updateSetCellValue(wmsInventoryLocationExtDTO.getInvWhCode()));
                            break;
                        }
                        case 15: {
                            //仓库名称
                            cell.setCellValue(updateSetCellValue(wmsInventoryLocationExtDTO.getInvWhName()));
                            break;
                        }
                        default:
                            break;
                    }
                }
            }
        }
        return workbook;
    }

    /**
     * 判断字符串设置值--非空过滤
     */
    private String updateSetCellValue(Object object) {
        if (!Objects.equals(object, null)) {
            String value = object.toString();
            if (StringUtils.isNotBlank(value)) {
                return value;
            }
        }
        return "";
    }

    /**
     * 初始化表格设置
     */
    private void initExcelSet(HSSFWorkbook workbook,
                              HSSFCellStyle titleStyle,
                              HSSFCellStyle cellStyle,
                              HSSFRow row,
                              String[] headers) {

        // 生成一个样式
        // 设置这些样式
        titleStyle.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
        titleStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//上下居中
        titleStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
        titleStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        titleStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        titleStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
        titleStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
        titleStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        // 生成一个字体
        HSSFFont font = workbook.createFont();
        font.setColor(HSSFColor.VIOLET.index);
        font.setFontHeightInPoints((short) 12);
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        // 把字体应用到当前的样式
        titleStyle.setFont(font);
        // 生成并设置另一个样式
        cellStyle.setFillForegroundColor(HSSFColor.WHITE.index);
        cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
        cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
        cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        // 生成另一个字体
        HSSFFont font2 = workbook.createFont();
        font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
        // 把字体应用到当前的样式
        cellStyle.setFont(font2);

        //设置表头样式
        for (short i = 0; i < headers.length; i++) {
            HSSFCell cell = row.createCell(i);
            cell.setCellStyle(titleStyle);
            HSSFRichTextString text = new HSSFRichTextString(headers[i]);
            cell.setCellValue(text);
        }
    }

    @Override
    public List<WmsInventoryDTO> getWmsInventoryInfo(Map<String, Object> paramMap) {
        List<WmsInventoryDTO> wmsInventoryDTOList = wmsInventoryExtMapper.queryWmsInventoryByInfo(paramMap);
        return wmsInventoryDTOList;
    }

    @Override
    public List<WmsInventoryLocationBO> getWmsInventoryLocation(Map<String, Object> paramMap) {
        List<WmsInventoryLocationBO> wmsInventoryLocationBOList = null;

        return wmsInventoryLocationBOList;
    }

    @Override
    public List<WmsInventoryLocation> listInventoryLocation(String invId) {
        return wmsInventoryLocationExtMapper.listInventoryLocationByInvId(invId);
    }

    /**
     * 库存查询 - 君马
     * <p>
     * 2018-1-23
     * 库存查询页面增加“物料代码”、“物料名称”、“颜色代码”、“颜色”字段显示，导出的文件中也需要包含这四个字段
     * 查询条件中增加“物料名称”、“颜色”、“库存状态”
     * 2018-4-23 因入库通知单重构,此方法过时 {@link WmsInventoryServiceImpl#queryInventoryListForJunMa}
     * </p>
     *
     * @param wmsInventoryQueryDTO 参数封装
     * @return 返回值
     * @throws Exception 异常
     */
    @Override
    @Deprecated
    public Map<String, Object> queryInventoryListForJunMaOld(WmsInventoryQueryDTO wmsInventoryQueryDTO) throws Exception {
        logger.info("WmsInventoryServiceImpl.queryInventoryListForJunMaOld param: {}", JSONObject.toJSONString(wmsInventoryQueryDTO));
        if (Objects.equals(wmsInventoryQueryDTO, null)) {
            logger.error("WmsInventoryServiceImpl.queryInventoryListForJunMaOld queryDTO must not be null");
            throw new BusinessException("分页参数不能为空");
        }
        Map<String, Object> resultMap = Maps.newHashMap();

        wmsInventoryQueryDTO.setLimitStart(wmsInventoryQueryDTO.getStartIndex());
        wmsInventoryQueryDTO.setLimitEnd(wmsInventoryQueryDTO.getPageSize());

        Map<String, Object> paramMap = ObjectToMapUtils.objectToMap(wmsInventoryQueryDTO);
        List<WmsInventoryLocationExtDTO> locationExtDTOList = wmsInventoryExtMapper.queryInventoryLocationForJunMa(paramMap);
        //计算库龄
        DateTimeFormatter format = DateTimeFormat.forPattern(DateUtils.YYYY_MM_DD);
        DateTime nowDate = new DateTime();
        if (CollectionUtils.isNotEmpty(locationExtDTOList)) {
            locationExtDTOList.stream()
                    .filter(dto -> dto != null && dto.getGmtCreate() != null)
                    .forEach(dto -> {
                        DateTime gmtCreate = new DateTime(dto.getGmtCreate());//入库时间
                        DateTime startTime = DateTime.parse(gmtCreate.toString(DateUtils.YYYY_MM_DD), format);
                        DateTime endTime = DateTime.parse(nowDate.toString(DateUtils.YYYY_MM_DD), format);
                        int days = Days.daysBetween(startTime, endTime).getDays();
                        if (days >= 0) {
                            dto.setWarehouseAge(days + 1);
                        }
                    });
        }
        resultMap.put("wmsInventoryList", locationExtDTOList);
        wmsInventoryQueryDTO.setPageNo(wmsInventoryQueryDTO.getStartIndex());
        wmsInventoryQueryDTO.setPageSize(wmsInventoryQueryDTO.getPageSize());
        wmsInventoryQueryDTO.setTotalRecord(wmsInventoryExtMapper.countForJunMaList(paramMap));
        resultMap.put("wmsInventoryBO", wmsInventoryQueryDTO);
        return resultMap;
    }


}
